<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Account;

use Srv\Apps\Apis\Account\Ctl\AccountCtl;
use Srv\Apps\Apis\Account\Ctl\TokenCtl;
use Srv\Apps\Proto\Enum\ErrCodeEnum;
use Srv\Apps\Proto\Enum\LangKeyEnum;
use Srv\Apps\Proto\VO\TokenVO;
use Srv\Libs\ConfModel\RouteConfData;
use Srv\Libs\Frame\ActionAbstract;
use Srv\Libs\Frame\AuthData;
use Srv\Libs\Frame\DTOAbstract;
use Srv\Libs\Frame\Lang;
use Srv\Libs\Frame\RequestHeader;
use Srv\Libs\Frame\ResponseData;
use Srv\Libs\Frame\VOAbstract;

final class TokenAct extends ActionAbstract
{
    /**
     * @url /acc/token/signout
     * @auth LOGIN
     * 令牌登出
     */
    public function signOutToken(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $DTOClass, $VOClass);
        $admUserId          = AuthData::getLoginUserId();
        $tokenKey           = AuthData::getLoginTokenKey();
        if($admUserId < 1 || strlen($tokenKey) !== 16) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_NOT_FOUND));
        $nonceInt           = 0;
        if(!AuthData::parseTokenKey($tokenKey, $nonceInt) || $nonceInt < 1) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_ERROR));
        $TokenCtl           = TokenCtl::tag();
        if(!$TokenCtl->signOutToken($admUserId, $nonceInt)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_DESTROY_FAIL));
        return ResponseData::rspSuccAuto();
    }

    /**
     * @url /acc/token/renew
     * @auth LOGIN
     * @rsp Srv.Apps.Proto.VO.TokenVO
     * 令牌续期
     */
    public function renewToken(RouteConfData $RouteConfData, ?DTOAbstract $DTOClass, ?VOAbstract $VOClass):bool
    {
        unset($RouteConfData, $DTOClass);
        if(!($VOClass instanceof TokenVO)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_SYS_PARAMS_ERROR, Lang::get(LangKeyEnum::LANG_SYS_PARAMS_ERROR));
        $admUserId          = AuthData::getLoginUserId();
        $tokenKey           = AuthData::getLoginTokenKey();
        if($admUserId < 1 || strlen($tokenKey) !== 16) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_NOT_FOUND));
        $nonceInt           = 0;
        if(!AuthData::parseTokenKey($tokenKey, $nonceInt) || $nonceInt < 1) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_ERROR));
        $AccountCtl         = AccountCtl::tag();
        // 是否允许登入
        if(!$AccountCtl->isAllowSigIn($admUserId)) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_SIGN_IN_FORBIDDEN_ERROR));
        $TokenCtl           = TokenCtl::tag();
        $utnrId             = $TokenCtl->getRenewUserTokenId($admUserId, $nonceInt);
        // 令牌无法续期
        if($utnrId < 1) return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_ERROR));
        // 续期新令牌
        $devId              = RequestHeader::getDevId();
        $appPlatform        = RequestHeader::getAppPlatform();
        $TokenVO            = null;
        if(!$TokenCtl->renewUserToken($admUserId, $nonceInt, $utnrId, $devId, $appPlatform, $TokenVO) || !($TokenVO instanceof TokenVO)){
            return ResponseData::rspErrAuto(ErrCodeEnum::ERR_FAIL, Lang::get(LangKeyEnum::LANG_TOKEN_RENEW_FAIL));
        }
        AuthData::init($TokenVO->getTokenStr(), $devId, $appPlatform);
        return ResponseData::rspSuccAuto('', $TokenVO);
    }
}